using System;
using System.Xml.Serialization;

namespace WeatherRouter.Model
{
	/// <summary>
	/// Summary description for Action.
	/// </summary>
	public class Action
	{        
        public enum ActionType { None, CurrentDay, NextDay, DayLight, Night, Morning, Day, Evening, NextSpan, NextAvg, NextMorning, Hourly }

        private int _hour;
        private int _minute;
        private ActionType _type;        
        private DateTime _lastSent;
        private Guid _feedGuid;        

        public int Hour
        {
            get { return _hour; }
            set { _hour = value; }
        }

        public int Minute
        {
            get { return _minute; }
            set { _minute = value; }
        }

        public ActionType Type
        {
            get { return _type; }
            set { _type = value; }
        }

        public DateTime LastSent
        {
            get { return _lastSent; }
            set { _lastSent = value; }
        }
        
        public Guid FeedGuid
        {
            get { return _feedGuid; }
            set { _feedGuid = value; }
        }

        [XmlIgnore]
        public Feed Feed
        {
            get
            {
                return Configuration.Instance.GetFeed(_feedGuid);
            }
            set
            {
                FeedGuid = value.Guid;
            }
        }

        /// <summary>
        /// Returns date with time when this action needs to be executed. Its value
        /// is calculated based on Hour and Minute properties.
        /// </summary>
        public DateTime NextAction
        {
            get
            {                
                DateTime nextAction = _lastSent.Date;
                nextAction = nextAction.Add(new TimeSpan(_hour, _minute, 0));                

                // If the specified time already passed, jump to the next day				 
                if (nextAction < _lastSent)
                {
                    nextAction = nextAction.AddDays(1);
                }

                return nextAction;
            }
        }

        /// <summary>
        /// Default constructor.
        /// </summary>
		public Action()
		{
            _lastSent = DateTime.Now;
		}

        /// <summary>
        /// Parses string value into ActionType.
        /// </summary>
        /// <param name="value">Value to be parsed.</param>
        /// <returns>ActionType Type of action.</returns>
		public static ActionType Parse(string value)
		{
            if (value == null)
                throw new ArgumentNullException("value");

            ActionType actionType = ActionType.None;

            try
            {
                actionType = (ActionType) Enum.Parse(typeof(ActionType), value, true);
            }
            catch (ArgumentException ex)
            {
                LogManager.Error("Could not parse value {0} to ActionType: {1}", value, ex.ToString());
            }

            return actionType;
		}

        /// <summary>
        /// Compares type of action to day span type. If both are night, morning, day
        /// or evening, its evaluated to true, otherwise false.
        /// </summary>
        /// <param name="daySpanType">DaySpanType to compare to.</param>
        /// <returns>True, if types are analogious, otherwise False.</returns>
		public bool Compare (DaySpan.DaySpanType daySpanType)
		{
            bool isEqual = false;
            if (this.Type == ActionType.Night &&
                daySpanType == DaySpan.DaySpanType.Night)
            {
                isEqual = true;
            }

            if (this.Type == ActionType.Morning &&
                daySpanType == DaySpan.DaySpanType.Morning)
            {
                isEqual = true;
            }

            if (this.Type == ActionType.Day &&
                daySpanType == DaySpan.DaySpanType.Day)
            {
                isEqual = true;
            }

            if (this.Type == ActionType.Evening &&
                daySpanType == DaySpan.DaySpanType.Evening)
            {
                isEqual = true;
            }

            return isEqual;                
		}         

        /// <summary>
        /// Converts object to its textual form.
        /// </summary>
        /// <returns>Object as a string.</returns>
		public override string ToString()
		{
            return Enum.Format(typeof(ActionType), _type, "G");
		}
	}
}
